package com.rickpan.controller;

import com.rickpan.common.ApiResponse;
import com.rickpan.entity.Project;
import com.rickpan.service.ProjectService;
import com.rickpan.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import java.util.List;

/**
 * 项目管理控制器
 * 
 * @author RickPan Team
 * @since 2024-01-15
 */
@RestController
@RequestMapping("/api/projects")
@Tag(name = "项目管理", description = "项目管理相关接口")
public class ProjectController {

    private static final Logger logger = LoggerFactory.getLogger(ProjectController.class);

    @Autowired
    private ProjectService projectService;

    /**
     * 创建项目
     */
    @PostMapping
    @Operation(summary = "创建项目", description = "在团队中创建新项目")
    public ApiResponse<Project> createProject(@Valid @RequestBody CreateProjectRequest request) {
        logger.info("创建项目请求: {}", request.getName());

        Long userId = SecurityUtils.getCurrentUserId();
        
        // 创建项目实体
        Project project = new Project();
        project.setTeamId(request.getTeamId());
        project.setName(request.getName());
        project.setDescription(request.getDescription());
        project.setPriority(request.getPriority());
        project.setStartDate(request.getStartDate());
        project.setEndDate(request.getEndDate());
        project.setProjectManagerId(request.getProjectManagerId());
        
        Project createdProject = projectService.createProject(project);
        return ApiResponse.success("项目创建成功", createdProject);
    }

    /**
     * 更新项目
     */
    @PutMapping("/{projectId}")
    @Operation(summary = "更新项目", description = "更新项目信息")
    public ApiResponse<Project> updateProject(
            @Parameter(description = "项目ID") @PathVariable Long projectId,
            @Valid @RequestBody UpdateProjectRequest request) {
        logger.info("更新项目请求: {}", projectId);

        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查权限
        if (!projectService.hasProjectManagePermission(projectId, userId)) {
            return ApiResponse.error("无权限管理此项目");
        }
        
        // 更新项目实体
        Project project = projectService.findById(projectId)
                .orElseThrow(() -> new RuntimeException("项目不存在"));
        
        project.setName(request.getName());
        project.setDescription(request.getDescription());
        project.setPriority(request.getPriority());
        project.setStartDate(request.getStartDate());
        project.setEndDate(request.getEndDate());
        project.setProjectManagerId(request.getProjectManagerId());
        
        Project updatedProject = projectService.updateProject(project);
        return ApiResponse.success("项目更新成功", updatedProject);
    }

    /**
     * 删除项目
     */
    @DeleteMapping("/{projectId}")
    @Operation(summary = "删除项目", description = "删除指定项目")
    public ApiResponse<Void> deleteProject(
            @Parameter(description = "项目ID") @PathVariable Long projectId) {
        logger.info("删除项目请求: {}", projectId);

        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查权限
        if (!projectService.hasProjectManagePermission(projectId, userId)) {
            return ApiResponse.error("无权限管理此项目");
        }
        
        projectService.deleteProject(projectId);
        return ApiResponse.success("项目删除成功");
    }

    /**
     * 获取项目详情
     */
    @GetMapping("/{projectId}")
    @Operation(summary = "获取项目详情", description = "根据ID获取项目详细信息")
    public ApiResponse<Project> getProject(
            @Parameter(description = "项目ID") @PathVariable Long projectId) {
        logger.info("获取项目详情: {}", projectId);

        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查权限
        if (!projectService.hasProjectViewPermission(projectId, userId)) {
            return ApiResponse.error("无权限查看此项目");
        }
        
        Project project = projectService.findById(projectId)
                .orElseThrow(() -> new RuntimeException("项目不存在"));
        
        return ApiResponse.success("获取成功", project);
    }

    /**
     * 获取团队项目列表
     */
    @GetMapping("/team/{teamId}")
    @Operation(summary = "获取团队项目列表", description = "获取指定团队的所有项目")
    public ApiResponse<List<Project>> getTeamProjects(
            @Parameter(description = "团队ID") @PathVariable Long teamId,
            @Parameter(description = "项目状态") @RequestParam(required = false) Project.Status status) {
        logger.info("获取团队项目列表: {}", teamId);

        List<Project> projects;
        if (status != null) {
            projects = projectService.findProjectsByTeamAndStatus(teamId, status);
        } else {
            projects = projectService.findProjectsByTeam(teamId);
        }
        
        return ApiResponse.success("获取成功", projects);
    }

    /**
     * 分页获取团队项目列表
     */
    @GetMapping("/team/{teamId}/page")
    @Operation(summary = "分页获取团队项目列表", description = "分页获取指定团队的项目")
    public ApiResponse<Page<Project>> getTeamProjectsPage(
            @Parameter(description = "团队ID") @PathVariable Long teamId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") int size,
            @Parameter(description = "项目状态") @RequestParam(required = false) Project.Status status) {
        logger.info("分页获取团队项目列表: {}, page: {}, size: {}", teamId, page, size);

        Pageable pageable = PageRequest.of(page, size);
        Page<Project> projects;
        
        if (status != null) {
            projects = projectService.findProjectsByTeamAndStatus(teamId, status, pageable);
        } else {
            projects = projectService.findProjectsByTeam(teamId, pageable);
        }
        
        return ApiResponse.success("获取成功", projects);
    }

    /**
     * 搜索项目
     */
    @GetMapping("/team/{teamId}/search")
    @Operation(summary = "搜索项目", description = "在团队中搜索项目")
    public ApiResponse<List<Project>> searchProjects(
            @Parameter(description = "团队ID") @PathVariable Long teamId,
            @Parameter(description = "搜索关键词") @RequestParam String keyword) {
        logger.info("搜索项目: {}, 关键词: {}", teamId, keyword);

        List<Project> projects = projectService.searchProjects(teamId, keyword);
        return ApiResponse.success("搜索成功", projects);
    }

    /**
     * 更新项目状态
     */
    @PutMapping("/{projectId}/status")
    @Operation(summary = "更新项目状态", description = "更新项目的状态")
    public ApiResponse<Void> updateProjectStatus(
            @Parameter(description = "项目ID") @PathVariable Long projectId,
            @Parameter(description = "新状态") @RequestParam Project.Status status) {
        logger.info("更新项目状态: {}, 状态: {}", projectId, status);

        Long userId = SecurityUtils.getCurrentUserId();
        
        // 检查权限
        if (!projectService.hasProjectManagePermission(projectId, userId)) {
            return ApiResponse.error("无权限管理此项目");
        }
        
        projectService.updateProjectStatus(projectId, status);
        return ApiResponse.success("状态更新成功");
    }

    /**
     * 分配项目经理
     */
    @PutMapping("/{projectId}/manager")
    @Operation(summary = "分配项目经理", description = "为项目分配项目经理")
    public ApiResponse<Void> assignProjectManager(
            @Parameter(description = "项目ID") @PathVariable Long projectId,
            @Parameter(description = "项目经理ID") @RequestParam Long projectManagerId) {
        logger.info("分配项目经理: {}, 经理ID: {}", projectId, projectManagerId);

        Long userId = SecurityUtils.getCurrentUserId();

        // 检查权限
        if (!projectService.hasProjectManagePermission(projectId, userId)) {
            return ApiResponse.error("无权限管理此项目");
        }

        projectService.assignProjectManager(projectId, projectManagerId);
        return ApiResponse.success("项目经理分配成功");
    }

    /**
     * 更新项目进度
     */
    @PutMapping("/{projectId}/progress")
    @Operation(summary = "更新项目进度", description = "更新项目的完成进度")
    public ApiResponse<Void> updateProjectProgress(
            @Parameter(description = "项目ID") @PathVariable Long projectId,
            @Parameter(description = "项目进度(0-100)") @RequestParam Integer progress) {
        logger.info("更新项目进度: {}, 进度: {}%", projectId, progress);

        Long userId = SecurityUtils.getCurrentUserId();

        // 检查权限
        if (!projectService.hasProjectManagePermission(projectId, userId)) {
            return ApiResponse.error("无权限管理此项目");
        }

        // 验证进度范围
        if (progress < 0 || progress > 100) {
            return ApiResponse.error("项目进度必须在0-100之间");
        }

        projectService.updateProjectProgress(projectId, progress);
        return ApiResponse.success("项目进度更新成功");
    }

    /**
     * 获取项目统计信息
     */
    @GetMapping("/team/{teamId}/statistics")
    @Operation(summary = "获取项目统计信息", description = "获取团队的项目统计数据")
    public ApiResponse<ProjectService.ProjectStatistics> getProjectStatistics(
            @Parameter(description = "团队ID") @PathVariable Long teamId) {
        logger.info("获取项目统计信息: {}", teamId);

        ProjectService.ProjectStatistics statistics = projectService.getProjectStatistics(teamId);
        return ApiResponse.success("获取成功", statistics);
    }

    /**
     * 创建项目请求DTO
     */
    public static class CreateProjectRequest {
        private Long teamId;
        private String name;
        private String description;
        private Project.Priority priority;
        private java.time.LocalDateTime startDate;
        private java.time.LocalDateTime endDate;
        private Long projectManagerId;

        // Getter 和 Setter
        public Long getTeamId() { return teamId; }
        public void setTeamId(Long teamId) { this.teamId = teamId; }

        public String getName() { return name; }
        public void setName(String name) { this.name = name; }

        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }

        public Project.Priority getPriority() { return priority; }
        public void setPriority(Project.Priority priority) { this.priority = priority; }

        public java.time.LocalDateTime getStartDate() { return startDate; }
        public void setStartDate(java.time.LocalDateTime startDate) { this.startDate = startDate; }

        public java.time.LocalDateTime getEndDate() { return endDate; }
        public void setEndDate(java.time.LocalDateTime endDate) { this.endDate = endDate; }

        public Long getProjectManagerId() { return projectManagerId; }
        public void setProjectManagerId(Long projectManagerId) { this.projectManagerId = projectManagerId; }
    }

    /**
     * 更新项目请求DTO
     */
    public static class UpdateProjectRequest {
        private String name;
        private String description;
        private Project.Priority priority;
        private java.time.LocalDateTime startDate;
        private java.time.LocalDateTime endDate;
        private Long projectManagerId;

        // Getter 和 Setter
        public String getName() { return name; }
        public void setName(String name) { this.name = name; }

        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }

        public Project.Priority getPriority() { return priority; }
        public void setPriority(Project.Priority priority) { this.priority = priority; }

        public java.time.LocalDateTime getStartDate() { return startDate; }
        public void setStartDate(java.time.LocalDateTime startDate) { this.startDate = startDate; }

        public java.time.LocalDateTime getEndDate() { return endDate; }
        public void setEndDate(java.time.LocalDateTime endDate) { this.endDate = endDate; }

        public Long getProjectManagerId() { return projectManagerId; }
        public void setProjectManagerId(Long projectManagerId) { this.projectManagerId = projectManagerId; }
    }
}
